package com.yangjun.utils;

import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.NestedNullException;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.util.TypeUtils;

import com.yangjun.entity.report.DwInventoryEntity;

public class ReflectUtil {
	/**
	 * 获取属性,忽略NestedNullException
	 * 
	 * @param bean
	 * @param name
	 * @return
	 */
	public static Object getProperty(Object bean, String name){
		try {
			return PropertyUtils.getProperty(bean, name);
		} catch (NestedNullException ignore) {
			return null;
		}catch(Exception e){
			throw new RuntimeException(e);
		}
	}
	public static void copyProps(Object source,Object target,String...ignoreProps){
		if(source instanceof Map){
			Map<Object,Object> sourceMap = (Map) source;
			Set<String> ignorePropSet = new HashSet<String>();
			if(ArrayUtils.isNotEmpty(ignoreProps)){
				for(String prop : ignoreProps){
					ignorePropSet.add(prop);
				}
			}
			for(Map.Entry<Object, Object> e: sourceMap.entrySet()){
				if(ignorePropSet.isEmpty()){
					setProperty(target,e.getKey().toString(), e.getValue());
				}else if(!ignorePropSet.contains(e.getKey())){
					setProperty(target, e.getKey().toString(), e.getValue());
				}
			}
		}else if(source instanceof List){
			List sourceList = (List)source;
			if(target instanceof List){
				List targetList = (List)target;
				for(Object obj:sourceList){
					targetList.add(obj);
				}
			}
			
		}else{
			BeanUtils.copyProperties(source, target, ignoreProps);
		}
	}
	
	@SuppressWarnings("unchecked")
	public static <T> T getConstValue(Class<?> clazz,String constName){
		Field field = ReflectUtil.getField(clazz, constName);
		if(field!=null){
			//修改权限强行将私有成员变量转变为公有成员变量
			field.setAccessible(true);
			try {
				//前提是字段一定时静态变量否则会报空指针异常，接口的变量都是静态变量public static final 
				Object object = field.get(null);
				if(object!=null){
					return (T) object;
				}
				return null;
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return null;
	}
	/**
	 * 获取字段
	 * @param clazz
	 * @param name
	 * @return
	 * @throws Exception
	 */
	public static Field getField(Class<?> clazz,String name){
		return ReflectionUtils.findField(clazz, name);
		
	}
	/**
	 * @Description 反射无参创建实例
	 * @param clazz
	 * @return
	 * @author yangjun
	 * @Date 2017年6月15日 上午11:57:44
	 */
	public static <T> T newInstance(Class<T> clazz){
		return BeanUtils.instantiate(clazz);
	}
	/**
	 * 设置Bean属性,类型自动转换,如果涉及日期转换,只支持long类型或者long值的字符串
	 * @param bean
	 * @param name
	 * @param value
	 * @param ignoreError 忽略找不到属性错误
	 * @throws Exception
	 */
	public static void setProperty(Object bean, String name, Object value) {
		if (value != null) {
			try {
				Class<?> type = getPropertyType(bean, name);
				if (type != null) {
					if (!value.getClass().equals(type)) {
						if (TypeUtils.isAssignable(Date.class, type) && value instanceof String) {
							try {
								value = new Date(Long.parseLong((String) value));
							} catch (NumberFormatException ignore) {
								SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");  
								value = format.parse(value.toString());
								System.out.println(name+"===="+value+"===="+type+"===="+value.getClass());
							}
						} else {
							//如果把一个字符串转换成数值,去除数值的,
							if(TypeUtils.isAssignable(Number.class, type)){
								value = StringUtils.deleteAny(value.toString(), ",");
							}
							value = ConvertUtils.convert(value, type);
						}
					}
				}
				PropertyUtils.setProperty(bean, name, value);
			} catch(Exception e){
				throw new RuntimeException(e);
			}
		}
	}
	/**
	 * 获取属性类型,忽略NestedNullException
	 * 
	 * @param bean
	 * @param name
	 * @return
	 */
	public static Class<?> getPropertyType(Object bean, String name) {
		try {
			return PropertyUtils.getPropertyType(bean, name);
		} catch (NestedNullException ignore) {
			return null;
		}catch(Exception e){
			throw new RuntimeException(e);
		}
	}

	/**
	 * 创建内嵌对象
	 * 
	 * @param bean
	 * @param name
	 */
	private static void createNestedBean(Object bean, String name){
		String[] names = name.split("[.]");
		if (names.length == 1)
			return;
		try {
			StringBuilder nestedName = new StringBuilder();
			for (int i = 0; i < names.length - 1; i++) {
				String n = names[i];
				if (i > 0) {
					nestedName.append("." + n);
				} else {
					nestedName.append(n);
				}
				Object val = PropertyUtils.getProperty(bean, nestedName.toString());
				if (val == null) {
					PropertyUtils.setProperty(bean, nestedName.toString(),
					PropertyUtils.getPropertyType(bean, nestedName.toString()).newInstance());
				}
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
	
	 /** 
	    * 获取属性名数组 
	    * */  
	   public static String[] getFiledName(Object o){  
	    Field[] fields=o.getClass().getDeclaredFields();  
	        String[] fieldNames=new String[fields.length];  
	    for(int i=0;i<fields.length;i++){  
	        fieldNames[i]=fields[i].getName(); 
	    }  
	    return fieldNames;  
	   }
}
